// Copyright 2025 the Xilem Authors
// SPDX-License-Identifier: Apache-2.0

use megalodon::entities::Status;
use xilem::core::{Arg, ViewArgument};
use xilem::masonry::properties::types::AsUnit;
use xilem::view::{
    CrossAxisAlignment, FlexExt, FlexSequence, FlexSpacer, MainAxisAlignment, flex_col, flex_row,
    inline_prose, label, prose, text_button,
};
use xilem::{FontWeight, TextAlign};

use crate::actions::Navigation;
use crate::{Avatars, status_html_to_plaintext};

mod timeline;
pub(crate) use timeline::Timeline;

mod thread;
pub(crate) use thread::thread;

mod media;

/// Renders the key parts of a Status, in a shared way.
///
/// This is the shared functionality between a timeline and the list of views.
// TODO: Determine our UX for boosting/reblogging.
// In particular, do we want to have the same design as "normal" Mastodon, where the
// avatar for the booster is shown in the "child" avatar.
fn base_status<State: ViewArgument>(
    status: &Status,
) -> impl FlexSequence<State, Navigation> + use<State> {
    // TODO: This really should be Arced or something.
    let status_clone: Status = status.clone();
    let acct_clone = status.account.acct.clone();
    // TODO: In theory, it's possible to reblog a reblog; it's not clear what happens in this case.
    debug_assert!(status.reblog.is_none(), "`base_status` can't show reblogs.");
    // We return a child list.
    (
        // Account info/message time
        flex_row((
            Avatars::avatar::<State, _>(status.account.avatar_static.clone()),
            flex_col((
                inline_prose(status.account.display_name.as_str())
                    .weight(FontWeight::SEMI_BOLD)
                    .text_alignment(TextAlign::Start)
                    .text_size(20.)
                    .flex(CrossAxisAlignment::Start),
                inline_prose(status.account.acct.as_str())
                    .weight(FontWeight::SEMI_LIGHT)
                    .text_alignment(TextAlign::Start)
                    .flex(CrossAxisAlignment::Start),
            ))
            .main_axis_alignment(MainAxisAlignment::Start)
            .gap(1.px()),
            FlexSpacer::Flex(1.0),
            text_button("Open Profile", move |_| {
                // TODO: We already actually just have the "account" here, so maybe
                // short-circuit re-loading the account?
                Navigation::LoadUser(acct_clone.clone())
            }),
            inline_prose(status.created_at.format("%Y-%m-%d %H:%M:%S").to_string())
                .text_alignment(TextAlign::End),
        ))
        .must_fill_major_axis(true),
        prose(status_html_to_plaintext(status.content.as_str())).flex(CrossAxisAlignment::Start),
        status
            .media_attachments
            .iter()
            .map(|attachment| {
                media::attachment::<State>(attachment).flex(CrossAxisAlignment::Start)
            })
            .collect::<Vec<_>>(),
        flex_row((
            label(format!("💬 {}", status.replies_count)).flex(1.0),
            label(format!("🔄 {}", status.reblogs_count)).flex(1.0),
            label(format!("⭐ {}", status.favourites_count)).flex(1.0),
            text_button("View Replies", move |_: Arg<'_, State>| {
                Navigation::LoadContext(status_clone.clone())
            }),
        ))
        // TODO: The "extra space" amount actually ends up being zero, so this doesn't do anything.
        .main_axis_alignment(MainAxisAlignment::SpaceEvenly)
        .flex(CrossAxisAlignment::Start),
    )
}
